﻿using System;
using System.Linq;
using System.ServiceModel;
using Framework.Core;
using Xunit;

namespace Framework.Tests.Core
{
    public class TypeExtensionHasAttributeTest
    {
        private static void AssertAttributes<T>(int count, bool inherit)
        {
            Assert.Equal(count, typeof (T).GetCustomAttributes<ServiceContractAttribute>(inherit).Count());
        }

        [Fact]
        public void Test_GetCustomAttributeOnInterfaceInherit_Succeed()
        {
            AssertAttributes<Contract>(1, true);
            AssertAttributes<CustomContract>(2, true);
            AssertAttributes<IContract>(1, true);
            AssertAttributes<ICustomContract>(1, true);
        }

        [Fact]
        public void Test_GetCustomAttributeOnInterface_Succeed()
        {
            AssertAttributes<Contract>(0, false);
            AssertAttributes<CustomContract>(0, false);
            AssertAttributes<IContract>(1, false);
            AssertAttributes<ICustomContract>(0, false);
        }

        private static void AssertHasAttribute<T>(bool hasAttribute)
        {
            Assert.Equal(hasAttribute, typeof (T).HasCustomAttribute<ServiceContractAttribute>());
        }

        [Fact]
        public void Test_HasCustomAttribute_Succeed()
        {
            AssertHasAttribute<Contract>(true);
            AssertHasAttribute<IContract>(true);
            AssertHasAttribute<CustomContract>(true);
            AssertHasAttribute<ICustomContract>(true);
            AssertHasAttribute<DummyContract>(false);
        }

        public class Contract : IContract
        {
            public void DoTest()
            {
                throw new NotImplementedException();
            }
        }

        public class CustomContract : Contract, ICustomContract
        {
            public void DoCustom()
            {
                throw new NotImplementedException();
            }
        }

        public class DummyContract
        {
        }

        [ServiceContract]
        public interface IContract
        {
            [OperationContract]
            void DoTest();
        }

        public interface ICustomContract : IContract
        {
            [OperationContract]
            void DoCustom();
        }
    }
}